package ca.clarity.hms.activity;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;


import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import ca.clarity.hms.util.RecMicToMp3;

/**
 * Interview 녹음 화면.
 * 
 * @author Junghun, Shin
 * @version 1.0
 *
 */
public class HmsRecordInterviewActivity extends Activity implements OnCompletionListener {

	public static String TAG = HmsRecordInterviewActivity.class.getSimpleName();
	
	HmsPatientRegistrationActivity hmsPatientRegistrationActivity = new HmsPatientRegistrationActivity();
	
	// 녹음 중인 임시파일이 저장될 경로.
	String applicationAudioTempDirectory = "/Android/data/ca.clarity.hms.activity/.AudioRecord/temp";
	
	// 최대 녹음 가능 시간.(초)
	public static final int RECORDING_TIME = 60000;		// 60 seconds
	
	// 녹음 진행 상태 바
	SeekBar recordSeekBar;
	private int mProgressCheckStepMs = 200;		// 녹음 및 재생에서 진행바의 갱신 간격(ms 단위) : 0.5초마다 체크
	private int mCurRecTimeMs = 0;				// 현재까지 녹음한 시간값
	private int mCurProgressTimeDisplay = 0;	// 녹음한 시간 보여주기 값 
	
	// 재생 중 표시
	SeekBar playSeekbar;		// 재생 진행 상태 바
	TextView mTvPlayMaxPoint;	// 전체 재생 시간
	
	// 녹음기.
	private RecMicToMp3 mRecMicToMp3;
	
	// 녹음 음성 재생기
	private MediaPlayer mPlayer = null;
	
	// 녹음 파일명.
	private String fileName;
	
	// 녹음을 시작 한다.
	private static final int THREAD_START_RECORD = 101;
	
	// 녹음을 중지 한다.
	private static final int THREAD_STOP_RECORD = 102;
	
	// 녹음을 일지정지 한다.
	private static final int THREAD_PAUSE_RECORD = 103;
	
	// 녹음을 재개한다.
	private static final int THREAD_RESUME_RECORD = 104;
	
	// 녹음을 재생한다.
	private static final int THREAD_PLAY_RECORD = 105;
	
	// 녹음 시작 버튼.
	Button startRecordButton;
	
	// 녹음 중지 버튼.
	Button stopRecordButton;
	
	// 녹음 일시정지 버튼.
	Button pauseRecordButton;
	
	// 녹음 재개 버튼.
	Button resumeRecordButton;
	
	// 녹음 재생 버튼.
	Button playRecordButton;
	
	// 녹음기 초기화.
	public void initRecMicToMp3(){
		fileName = System.currentTimeMillis() +".mp3";	
		String tempFileName = tempMP3FileName();
		
		Log.i(TAG, "initRecMicToMp3 tempFileName : " + tempFileName);
		
		mRecMicToMp3 = new RecMicToMp3(tempFileName, 8000);				// 8000 또는 44100
	}
	
	/*
	 * temp 파일명 구하기 - 현시각 ms 단위로. 
	 */
	public String tempMP3FileName() {
		// 디렉토리 없으면 생성
		File file = new File(Environment.getExternalStorageDirectory().getPath(), applicationAudioTempDirectory);
		
		if(!file.exists()){
			file.mkdirs();
		}
		
		return Environment.getExternalStorageDirectory() + applicationAudioTempDirectory + "/" + fileName;		
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		Log.i(TAG, "onCreate");
		
		// 화면 상단의 기본 타이틀바를 제거 한다.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
		setContentView(R.layout.activity_hms_record_interview);
		
		// 녹음기 초기화
		initRecMicToMp3();
		
		mRecMicToMp3.setHandle(new Handler() {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case RecMicToMp3.MSG_REC_STARTED:

					// SeekBar 
					mCurRecTimeMs = 0;
					mCurProgressTimeDisplay = 0;
					mProgressHandler.sendEmptyMessageDelayed(0, mProgressCheckStepMs);		// SeekBar의 상태를 mProgressCheckStepMs 후 체크 시작

					// 화면 UI 변경
//					recordedTimeTxt.setText("0");		// 녹음 진행 상황 0초 세팅(초기화)


					break;
				case RecMicToMp3.MSG_REC_STOPPED:				// 정상 정지
					break;
				case RecMicToMp3.MSG_ERROR_GET_MIN_BUFFERSIZE:
					Toast.makeText(HmsRecordInterviewActivity.this,
							"녹음을 시작하지 못했습니다. 이기기가 녹음을 지원하지 않을 수 있습니다.",
							Toast.LENGTH_LONG).show();
					break;
				case RecMicToMp3.MSG_ERROR_CREATE_FILE:
					Toast.makeText(HmsRecordInterviewActivity.this, 
							"파일을 생성할 수 없습니다.",
							Toast.LENGTH_LONG).show();
					break;
				case RecMicToMp3.MSG_ERROR_REC_START:
					Toast.makeText(HmsRecordInterviewActivity.this, 
							"녹음을 시작할 수 없습니다.",
							Toast.LENGTH_LONG).show();
					break;
				case RecMicToMp3.MSG_ERROR_AUDIO_RECORD:
					Toast.makeText(HmsRecordInterviewActivity.this, 
							"녹음을 할 수 없습니다.",
							Toast.LENGTH_LONG).show();
					break;
				case RecMicToMp3.MSG_ERROR_AUDIO_ENCODE:
					Toast.makeText(HmsRecordInterviewActivity.this, 
							"인코딩에 실패했습니다.",
							Toast.LENGTH_LONG).show();
					break;
				case RecMicToMp3.MSG_ERROR_WRITE_FILE:
					Toast.makeText(HmsRecordInterviewActivity.this, 
							"파일 쓰기에 실패했습니다.",
							Toast.LENGTH_LONG).show();
					break;
				case RecMicToMp3.MSG_ERROR_CLOSE_FILE:
					Toast.makeText(HmsRecordInterviewActivity.this, 
							"파일 쓰기에 실패했습니다.",
							Toast.LENGTH_LONG).show();
					break;
				default:
					break;
				}
			}
		});
		
		// seek bar.
		recordSeekBar = (SeekBar)findViewById(R.id.recordSeekbar);
		
		/*
		 * 녹음 진행바를 수동 조작이 불가능하게 한다. 
		 */
		recordSeekBar.setMax(RECORDING_TIME);
		recordSeekBar.setOnTouchListener(new OnTouchListener(){
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return true;
			}
		});
		
		// 녹음 시작 버튼.
		startRecordButton = (Button)findViewById(R.id.startRecordButton);
		startRecordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	mHandler.sendMessage(mHandler.obtainMessage(THREAD_START_RECORD));
            }
        });
		
		// 녹음 중지 버튼.
		stopRecordButton = (Button)findViewById(R.id.stopRecordButton);
		stopRecordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	mHandler.sendMessage(mHandler.obtainMessage(THREAD_STOP_RECORD));
            }
        });
		
		// 녹음 일시정지 버튼.
		pauseRecordButton = (Button)findViewById(R.id.pauseRecordButton);
		pauseRecordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	mHandler.sendMessage(mHandler.obtainMessage(THREAD_PAUSE_RECORD));
            }
        });
		
		// 녹음 재개 버튼.
		resumeRecordButton = (Button)findViewById(R.id.resumeRecordButton);
		resumeRecordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	mHandler.sendMessage(mHandler.obtainMessage(THREAD_RESUME_RECORD));
            }
        });
		
		// 녹음 재생 버튼.
		playRecordButton = (Button)findViewById(R.id.playRecordButton);
		playRecordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	mHandler.sendMessage(mHandler.obtainMessage(THREAD_PLAY_RECORD));
            }
        });
	}
	
	/**
	 * 필요한 핸들러를 등록해서 사용한다.
	 */
	private Handler mHandler = new Handler() {
		@Override
        public void handleMessage(Message msg) {
			switch (msg.what) {
			// 녹음을 시작한다.
			case THREAD_START_RECORD : 
				runOnUiThread(startRecording);
				break;
			// 녹음을 중지 한다.
			case THREAD_STOP_RECORD : 
				runOnUiThread(stopRecording);
				break;
			// 녹음을 일지정지 한다.
			case THREAD_PAUSE_RECORD : 
				runOnUiThread(pauseRecording);
				break;
			// 녹음을 재개 한다.
			case THREAD_RESUME_RECORD : 
				runOnUiThread(resumeRecording);
				break;
			// 녹음을 재생 한다.
			case THREAD_PLAY_RECORD : 
				runOnUiThread(playRecording);
				break;
			}
		}
	};
	
	/**
	 * 녹음을 시작한다
	 */
	private Runnable startRecording = new Runnable() {
		@Override
		public void run() {
			// 녹음 시작
			mRecMicToMp3.start();		// 나머지 변경사항은 녹음이 성공적으로 시작되면 호출되도록 함
		}
	};
	
	/**
	 * 녹음을 중지 한다
	 */
	private Runnable stopRecording = new Runnable() {
		@Override
		public void run() {

			// SeekBar
			mCurRecTimeMs = -999;	
			mProgressHandler.sendEmptyMessageDelayed(0, 0);				    // SeekBar의 상태를 즉시 체크 

			// 녹음 완료
			mRecMicToMp3.stop();
		}
	};
	
	/**
	 * 녹음을 일시 정지한다
	 */
	private Runnable pauseRecording = new Runnable() {
		@Override
		public void run() {
			mRecMicToMp3.pause();
		}
	};
	
	/**
	 * 녹음을 재개한다
	 */
	private Runnable resumeRecording = new Runnable() {
		@Override
		public void run() {
			mRecMicToMp3.resume();
		}
	};
	
	/**
	 * 녹음한 음성을 재생한다
	 */
	private Runnable playRecording = new Runnable() {
		@Override
		public void run() {
			// 음성을 재생한다
			initMediaPlayer();
			startPlay();
		}
	};
	
	/*
	 * 미디어 플레이어 초기화
	 */
	private void initMediaPlayer() {
		// 미디어 플레이어 생성
		if(mPlayer == null) {
			mPlayer = new MediaPlayer();
		} else{
			mPlayer.reset();
		}
		
		mPlayer.setOnCompletionListener(this);
		String fullFilePath = tempMP3FileName();
		
		Log.i(TAG, "initMediaPlayer fullFilePath : " + fullFilePath);
		
		// fullFilePath 을 patient registration activity 에 넘겨 준다.
		Intent i = getIntent();
		i.putExtra("interviewFullFilePath", fullFilePath);
		setResult(RESULT_OK, i);

		try {
			mPlayer.setDataSource(fullFilePath);
			mPlayer.prepare();   
			int point = mPlayer.getDuration();
			playSeekbar.setMax(point);

			int maxMinPoint = point / 1000 / 60;
			int maxSecPoint = (point / 1000) % 60;
			String maxMinPointStr = "";
			String maxSecPointStr = "";

			if (maxMinPoint < 10)
				maxMinPointStr = "0" + maxMinPoint + ":";
			else
				maxMinPointStr = maxMinPoint + ":";

			if (maxSecPoint < 10)
				maxSecPointStr = "0" + maxSecPoint;
			else
				maxSecPointStr = String.valueOf(maxSecPoint);

			mTvPlayMaxPoint.setText(maxMinPointStr + maxSecPointStr);		// 시간 값?

			playSeekbar.setProgress(0);	// init
		} catch(Exception e) {
		}
	}

	// 재생 시작
	private void startPlay() {
		try {
			mPlayer.start();

			// SeekBar의 상태를 mProgressCheckStepMs 마다 체크      
//			mProgressHandler2.sendEmptyMessageDelayed(0, mProgressCheckStepMs);
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(this, "error : " + e.getMessage(), 0).show();
		}
	}
	
	// 녹음시 SeekBar 처리
	Handler mProgressHandler = new Handler() {
		public void handleMessage(Message msg) {
			// 특정 조건 (현재 녹음중) 에만 동작하도록 함
			if(mRecMicToMp3.isRecording()) {		
				if(mRecMicToMp3.isPuased()) {
					mProgressHandler.sendEmptyMessageDelayed(0, mProgressCheckStepMs);	// 녹음이 완료될때까지 체크는 계속 하고 있어야 함
				} else {
					mCurRecTimeMs = mCurRecTimeMs + mProgressCheckStepMs;
					mCurProgressTimeDisplay = mCurProgressTimeDisplay + mProgressCheckStepMs;
					// 녹음시간이 음수이면 정지버튼을 눌러 정지시켰음을 의미하므로 
					// SeekBar는 그대로 정지시키고 레코더를 정지시킨다. 
					if (mCurRecTimeMs < 0) {
						
					}
					// 녹음시간이 아직 최대녹음제한시간보다 작으면 녹음중이라는 의미이므로
					// SeekBar의 위치를 옮겨주고 0.1초 후에 다시 체크하도록 한다. 
					else if (mCurRecTimeMs < (30000)) {	// 2000 -> usableSecond -> SendMeConstant.RECORDING_TIME
						recordSeekBar.setProgress(mCurProgressTimeDisplay);
						mProgressHandler.sendEmptyMessageDelayed(0, mProgressCheckStepMs);
//						recordedTimeTxt.setText((mCurRecTimeMs/1000)+"");
					}
					// 녹음시간이 최대 녹음제한 시간보다 크면 녹음을 정지 시킨다. 
					else {
						mHandler.sendMessage(mHandler.obtainMessage(THREAD_STOP_RECORD));
					}
				}
			}
		}
	};
	
	// 재생시 SeekBar 처리
//	Handler mProgressHandler2 = new Handler() {
//		public void handleMessage(Message msg) {
//			if (mPlayer == null) return;
//			try {
//				if (mPlayer.isPlaying()) {
//					//					Log.d(TAG,"mPlayer.getCurrentPosition():"+mPlayer.getCurrentPosition());
//					if(mPlayer.getCurrentPosition()>0) {		// 재생 끝나고나서도 동작되어 0이 표시되는 경우가 있기 때문에 0은 표시해주지 않도록 처리
//						playSeekbar.setProgress(mPlayer.getCurrentPosition());
//					}
//					
//					mProgressHandler2.sendEmptyMessageDelayed(0, mProgressCheckStepMs);
//				}
//			} catch (IllegalStateException e) {
//				
//			} catch (Exception e) {
//				
//			}
//		}
//	};

	@Override
	public void onCompletion(MediaPlayer mp) {
		// TODO Auto-generated method stub
		// 재생이 끝났으므로 진행바를 가장 끝으로 위치시킨다
//		playSeekbar.setProgress(mPlayer.getDuration());
		// 재생이 종료되면 즉시 SeekBar 메세지 핸들러를 호출한다. 
//		mProgressHandler2.sendEmptyMessageDelayed(0, 0);
	}
}
